import SparkMD5 from "spark-md5";
import api from '@/api'

let nowStatus = { // 当前上传状态
	totalChunks: 0, // 总分片数
	fileType: '', // 文件类型
	currentChunk: 0, // 当前分片
	uploadedIdxs: [], // 已上传分片索引
	uploadJindus: [], // 已上传分片进度
}
let config = { // 上传配置
	chunkSize: 1024 * 1024 * 2,
	maxThreads: 2,
}
const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;

function myConsoleLog() {
	/*console.log = (function (oriLogFunc) {
		return function () {
			if (sign) {
				oriLogFunc.apply(this, arguments);
			}
		}
	})(console.log)*/
	// console.log(...data)
	console.log.apply(console,arguments);
}

// 计算进度
// eslint-disable-next-line no-unused-vars
function calcProcess() {
	let jindu = 0;
	for (let i = 0; i < nowStatus.uploadJindus.length; i++) {
		if (nowStatus.uploadJindus[i]) {
			jindu += nowStatus.uploadJindus[i];
		}
	}
	return Math.round(jindu / nowStatus.totalChunks);
}

function getFileMd5(file) {
	if (!file) {
		return Promise.reject('文件不存在')
	}
	myConsoleLog('开始读取文件md5')
	return new Promise((resolve, reject) => {
		let chunks = Math.ceil(file.size / config.chunkSize),
			currentChunk = 0,
			spark = new SparkMD5.ArrayBuffer(),
			fileReader = new FileReader();

		nowStatus.totalChunks = chunks

		fileReader.onload = function (e) {
			currentChunk++;
			console.log('read chunk nr', currentChunk, 'of', chunks);
			spark.append(e.target.result);                   // Append array buffer
			if (currentChunk < chunks) {
				loadNext();
			} else {
				console.log('finished loading');
				resolve(spark.end());
			}
		};
		fileReader.onerror = function () {
			console.warn('oops, something went wrong.');
			reject();
		};
		function loadNext() {
			let start = currentChunk * config.chunkSize,
				end = ((start + config.chunkSize) >= file.size) ? file.size : start + config.chunkSize;
			fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
		}
		loadNext();
	})
}

function checkMd5Fn(params) {
	/*return new Promise((resolve, reject) => {
		reject('未传入checkMd5Fn');
	});*/
	// TODO 改这里成自己的
	return api.gdshop.attachment.checkMd5(params)
}

// eslint-disable-next-line no-unused-vars
function uploadChunkFn(params, config) {
	/*return new Promise((resolve, reject) => {
		reject('未传入uploadChunkFn');
	});*/
	// TODO 改这里成自己的
	return api.gdshop.attachment.uploadChunk(params, config)
}

// eslint-disable-next-line no-unused-vars
function mergeChunkFn(params) {
	/*return new Promise((resolve, reject) => {
		reject('未传入mergeChunkFn');
	});*/
	// TODO 改这里成自己的
	return api.gdshop.attachment.mergeChunk(params)
}

export const uploadFile = async (file,params = {}) => {
	nowStatus.uploadedIdxs.length = 0;
	nowStatus.uploadJindus.length = 0;
	nowStatus.currentChunk = 0;
	const fileMd5 = await getFileMd5(file)
	myConsoleLog('fileMd5', fileMd5)
	const checkMd5Res = await checkMd5Fn({
		fileMd5: fileMd5,
		fileSize: file.size,
		fileType: file.type
	})
	myConsoleLog('checkMd5Res', checkMd5Res)
	// 21001 文件存在
	if (checkMd5Res.code === 21001) {
		/*return Promise.resolve({
			code: 0,
			data: checkMd5Res.data,
			message: '秒传成功'
		});*/

		return Promise.resolve(checkMd5Res);
	}
	// 21003 断点续传
	if (checkMd5Res.code === 21003) {
		// 处理已上传
		var obj = checkMd5Res.data;
		let tmpUploadedIdxs = [];
		Object.keys(obj).forEach(function(key){
			// 转换成数字
			tmpUploadedIdxs.push(parseInt(obj[key]));
		});
		// 已经完成的分片，赋值进度
		for(let i=0; i< tmpUploadedIdxs.length; i++){
			nowStatus.uploadJindus[tmpUploadedIdxs[i]] = 100;
		}
		nowStatus.uploadedIdxs = tmpUploadedIdxs;
		myConsoleLog('已上传', nowStatus.uploadedIdxs)
	}
	// 21002 文件不存在
	if (checkMd5Res.code === 21002) {
		myConsoleLog("正常流程")
	}

	return new Promise((resolve, reject) => {
		const chunkSize = config.chunkSize;
		let chunkIndex = 0;
		nowStatus.totalChunks = Math.ceil(file.size / chunkSize);
		const fun = function (start, end) {
			let fileReader = new FileReader();
			fileReader.onload = function (e) {
				console.log('chunkIndex',chunkIndex)
				var s = new SparkMD5.ArrayBuffer();
				s.append(e.target.result);                   // Append array buffer
				var pieceMd5 = s.end();
				const formData = new FormData();
				formData.append('file', new Blob([e.target.result]));
				formData.append('filename', file.name);
				formData.append('chunks', nowStatus.totalChunks);
				formData.append('index', chunkIndex);
				formData.append('fileMd5', fileMd5);
				// formData.append('group_id', this.menuId);
				formData.append('type', file.type);
				formData.append('pieceMd5', pieceMd5);
				formData.append('fileSize', file.size);
				formData.append('lastModified', file.lastModified);
				uploadChunkFn(formData,{
					onUploadProgress: e => {
						nowStatus.uploadJindus[chunkIndex] = Math.round(e.loaded / e.total * 100);
						e.jindu = calcProcess();
						// console.log('e.jindu',e.jindu)
						if (params.onProgress) {
							params.onProgress(e);
						}
					}
				}).then(res => {
					if (res.code === 0) {
						if (chunkIndex < nowStatus.totalChunks) {
							loadNext();
							// 写入已上传index
						}
					} else {
						if (res.code === 21004) {
							// 调用合并接口
							mergeChunkFn({
								fileMd5: fileMd5,
								filename: file.name,
								chunks: nowStatus.totalChunks,
								fileSize: file.size,
								lastModified: file.lastModified,
								type: file.type,
								// group_id: that.menuId
							}).then(resmc => {
								resolve(resmc);
							}).catch(errmc => {
								reject(errmc);
							})
						} else {
							reject(res);
						}
					}
				}).catch((err) => {
					reject(err);
				})
			}
			fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
		};

		function loadNext() {
			var start = chunkIndex * chunkSize,
				end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;

			chunkIndex++;
			if (!nowStatus.uploadedIdxs.includes(chunkIndex)) {
				fun(start, end);
			}
			else {
				loadNext();
			}
		}
		// loadNext();
		// 根据线程，启动
		for (let i = 1; i < config.maxThreads; i++) {
			setTimeout(() => {
				loadNext();
			}, 200)
		}
	})
}
export const setConfig = (_config) => {
	config.chunkSize = _config.chunkSize || config.chunkSize;
	config.maxThreads = _config.maxThreads || config.maxThreads;
}
export default {
	// 上传文件
	uploadFile(file) {
		return new Promise((resolve, reject) => {
			// 1.检查文件是否已经上传过
			this.checkMd5Fn({
				md5: file.md5,
				fileName: file.name,
				fileSize: file.size,
				fileType: file.type,
			}).then(res => {
				if (res.code == 0) {
					// 2.文件已上传过
					resolve(res);
				} else {
					// 3.文件未上传过
					this.uploadFileChunk(file).then(res => {
						resolve(res);
					}).catch(err => {
						reject(err);
					});
				}
			}).catch(err => {
				reject(err);
			});
		});
	}
}
